<?php

App::uses('AppController', 'Controller');

abstract class CrudController extends AppController
{
    public $_model;

    public function beforeFilter() {
        $this->Security->validatePost = false;
        $this->Security->csrfCheck = false;
        parent::beforeFilter();
    }

    /**
     * A C C I O N E S
     */
    final public function create() {
        $this->request->allowMethod('get');
        $m = $this->_model;
        $this->loadModel($m);
        $models = json_decode($this->request->query['models']);
        $model = $models[0];
        $result = false;
        try {
            $data = $this->c($model);
            if (is_array($data) === true) {
                if (($resp = $this->beforeCreate($data)) === true) {
                    $newRecord = $this->$m->insert($data);
                    $this->afterCreate($newRecord[$m]);
                    $result = $newRecord[$m];
                } else {
                    $result = $resp;
                }
            } else {
                $result = NULL;
            }
        } catch (PDOException $exc) {
            switch ($exc->getCode()) {
                default:
                    throw $exc;
            }
        }
        $result = $this->resultCreate($result);
        $this->set(array('records' => $result, '_serialize' => 'records'));
        $this->viewClass = 'Json';
    }

    /**
     * P R I V A D O S  para R E D E F I N I R
     */
    abstract protected function c($model);

    protected function beforeCreate(&$newRecord)
    {
        return true;
    }

    protected function afterCreate(&$newRecord)
    {

    }

    protected function resultCreate($model)
    {
        return $model;
    }

    final public function read($param = null) {
        $m = $this->_model;
        $this->loadModel($m);
        $this->request->allowMethod('get');
        $this->set(array('records' => $this->getRecords($param), '_serialize' => 'records'));
        $this->viewClass = 'Json';
    }

    abstract protected function getRecords($argList);

    final public function update() {
        $this->request->allowMethod('get');
        $m = $this->_model;
        $this->loadModel($m);
        $models = json_decode($this->request->query['models']);
        $model = $models[0];
        $result = false;
        try {
            $id = $this->id($model);
            $data = $this->u($model);
            if ($this->beforeUpdate($id, $data) === true) {
                $updatedModel = $this->$m->update($id, $data);
                $result = $updatedModel[$m];
                $this->afterUpdate($id, $result);
            }
        } catch (PDOException $exc) {
            switch ($exc->getCode()) {
//                case 23000:
//                    $this->response->statusCode(404);
//                    break;
//                case 45000:
//                    $this->response->statusCode(404);
//                    break;
                default:
                    throw $exc;
            }
        }
        $result = $this->resultUpdate($id, $result);
        $this->set(array('records' => $result, '_serialize' => 'records'));
        $this->viewClass = 'Json';
    }

    protected function id($model)
    {
        return $model->id;
    }

    abstract protected function u($model);

    protected function beforeUpdate($id, &$updatedModel)
    {
        return true;
    }

    protected function afterUpdate($id, &$updatedModel)
    {

    }

    protected function resultUpdate($id, $result)
    {
        return $result;
    }

    final public function destroy()
    {
        $this->request->allowMethod('get');
        $m = $this->_model;
        $this->loadModel($m);
        $id = $this->request->query['id'];
        $result = false;
        if ($this->beforeDestroy($id)) {
            $deletedModel = $this->$m->destroy($id, $m::STATUS_DISABLED);
            $this->afterDestroy($deletedModel[$m]);
            $result = $deletedModel[$m];
        }
        $this->set(array('records' => $result, '_serialize' => 'records'));
        $this->viewClass = 'Json';
    }

    protected function beforeDestroy($id)
    {
        return true;
    }

    protected function afterDestroy(&$destroyedModel) {
        
    }

    final public function get($id)
    {
        $m = $this->_model;
        $this->$m->id = $id;
        $record = $this->$m->read();
        $this->set(array('record' => $record[$m], '_serialize' => 'record'));
        $this->viewClass = 'Json';
    }
}
